package com.suntop.carousel.qlmediaplay.banner;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.RelativeLayout;

import com.suntop.carousel.qlmediaplay.adapter.BasicFragmentBannerAdapter;
import com.suntop.carousel.qlmediaplay.bean.PlayerState;
import com.suntop.carousel.qlmediaplay.field.Field_Banner;
import com.suntop.carousel.qlmediaplay.field.Field_Banner_Player;
import com.suntop.carousel.qlmediaplay.tools.AnimationTools;
import com.suntop.carousel.qlmediaplay.tools.Rxbus;

import java.lang.reflect.Field;
import java.util.ArrayList;

import androidx.annotation.IntRange;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.CompositePageTransformer;
import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import io.reactivex.functions.Consumer;

@SuppressLint("NewApi")
public abstract class NewViewPagerBanner<T, AD extends RecyclerView.Adapter<HV>,
        HV extends RecyclerView.ViewHolder>
        extends RelativeLayout {
    protected AD adapter;
    protected ViewPager2 viewPager2;
    protected ViewPager2.OnPageChangeCallback changeCallback;
    protected Indicator indicator;//指示器
    protected CompositePageTransformer compositePageTransformer;//动效

    private int needPage = Field_Banner.NORMAL_COUNT;
    private int sidePage = needPage / Field_Banner.NORMAL_COUNT;

    private final int scaledTouchSlop;//表示是否可以继续滑动
    private boolean isBeginPagerChange = true;
    private boolean isTaskPostDelayed = false;
    private boolean isNeedAnimation = false;
    private int tempPosition;//viewpager 页面地标
    private float startX, startY, lastX, lastY;
    private ProxyLayoutManger proxyLayoutManger;

    private int program_list_id;
    private int program_id;
    private int uuid;
    private boolean isSyn;


    public NewViewPagerBanner(Context context) {
        this(context, null);
    }

    public NewViewPagerBanner(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public NewViewPagerBanner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() >> 1;
        initViewPager2(context);
    }

    private void initViewPager2(Context context) {
        if (viewPager2 != null) {
            release();
        }
        changeCallback = new onPagerChangeCallBack();
        viewPager2 = new ViewPager2(context);

        viewPager2.setPageTransformer(compositePageTransformer = new CompositePageTransformer());
        viewPager2.registerOnPageChangeCallback(changeCallback);
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT
                , LayoutParams.MATCH_PARENT);
        layoutParams.addRule(Gravity.CENTER);
        addView(viewPager2, layoutParams);
        initAdapter();
    }

    private void initAdapter() {
        adapter = getAdapterForViewPager();
        viewPager2.setAdapter(adapter);
        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
            @Override
            public void onItemRangeInserted(int positionStart, int itemCount) {
                super.onItemRangeInserted(positionStart, itemCount);
                setCurrentItem(0, false);
                if (indicator != null) {
                    indicator.initIndicatorCount(getRealCount(), viewPager2.getCurrentItem());
                }
            }
        });

    }

    public void setSyn(boolean syn) {
        isSyn = syn;
    }

    /**
     * 初始化管理器
     */
    private void initLayoutManager(int scrollTime) {
        try {
            if (proxyLayoutManger != null) {
                proxyLayoutManger.setPagerScrollDuration(scrollTime);
                return;
            }
            //控制切换速度，采用反射方。法方法只会调用一次，替换掉内部的RecyclerView的LinearLayoutManager
            RecyclerView recyclerView = (RecyclerView) viewPager2.getChildAt(0);
            recyclerView.setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);

            LinearLayoutManager o = (LinearLayoutManager) recyclerView.getLayoutManager();
            proxyLayoutManger = new ProxyLayoutManger(getContext(), o);
            proxyLayoutManger.setPagerScrollDuration(scrollTime);
            recyclerView.setLayoutManager(proxyLayoutManger);

            Field mRecyclerView = RecyclerView.LayoutManager.class.getDeclaredField("mRecyclerView");
            mRecyclerView.setAccessible(true);
            mRecyclerView.set(o, recyclerView);

            Field LayoutMangerField = ViewPager2.class.getDeclaredField("mLayoutManager");
            LayoutMangerField.setAccessible(true);
            LayoutMangerField.set(viewPager2, proxyLayoutManger);

            Field pageTransformerAdapterField = ViewPager2.class.getDeclaredField("mPageTransformerAdapter");
            pageTransformerAdapterField.setAccessible(true);
            Object mPageTransformerAdapter = pageTransformerAdapterField.get(viewPager2);
            if (mPageTransformerAdapter != null) {
                Class<?> aClass = mPageTransformerAdapter.getClass();
                Field layoutManager = aClass.getDeclaredField("mLayoutManager");
                layoutManager.setAccessible(true);
                layoutManager.set(mPageTransformerAdapter, proxyLayoutManger);
            }
            Field scrollEventAdapterField = ViewPager2.class.getDeclaredField("mScrollEventAdapter");
            scrollEventAdapterField.setAccessible(true);
            Object mScrollEventAdapter = scrollEventAdapterField.get(viewPager2);
            if (mScrollEventAdapter != null) {
                Class<?> aClass = mScrollEventAdapter.getClass();
                Field layoutManager = aClass.getDeclaredField("mLayoutManager");
                layoutManager.setAccessible(true);
                layoutManager.set(mScrollEventAdapter, proxyLayoutManger);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    private class onPagerChangeCallBack extends ViewPager2.OnPageChangeCallback {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//            super.onPageScrolled(position, positionOffset, positionOffsetPixels);
            if (indicator != null) {
                indicator.onPageScrolled(toRealPosition(position), positionOffset, positionOffsetPixels);
            }
            if (positionOffset == 0) {
                Log.e("已经选择的", position + "    ===");
                int realPosition = toRealPosition(position);
                if (isTaskPostDelayed) {
                    if (isSyn){
                        callBackPageScrolled(realPosition);
                        return;
                    }
                    sendPlayState(realPosition, PlayerState.State.Start);
                }
            }
        }

        @Override
        public void onPageSelected(int position) {
//            super.onPageSelected(position);
            if (getRealCount() > 1) {
                tempPosition = position;
            }
            int realPosition = toRealPosition(position);
            if (adapter != null && indicator != null)
                indicator.initIndicatorCount(getRealCount(), realPosition);
            if (isBeginPagerChange) {
                if (indicator != null) {
                    indicator.onPageSelected(realPosition);
                }
            }

        }


        @Override
        public void onPageScrollStateChanged(int state) {
//            super.onPageScrollStateChanged(state);
            switch (state) {
                case ViewPager2.SCROLL_STATE_DRAGGING:
                    int realCount = getRealCount();
                    if (tempPosition == (sidePage - 1)) {
                        isBeginPagerChange = false;
                        viewPager2.setCurrentItem(realCount + tempPosition, false);
                    } else if (tempPosition == realCount + sidePage) {
                        isBeginPagerChange = false;
                        viewPager2.setCurrentItem(sidePage, false);
                    } else {
                        isBeginPagerChange = true;
                    }
                    break;
            }
            if (indicator != null) {
                indicator.onPageScrollStateChanged(state);
            }
        }
    }

    protected abstract void callBackPageScrolled(int realPosition);

    private int toRealPosition(int position) {
        int realPosition = 0;
        if (adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            realPosition = ((BasicFragmentBannerAdapter) adapter).toRealPosition(position);
        }
        return realPosition;
    }

    private int getRealCount() {
        int realPosition = 0;
        if (adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            realPosition = ((BasicFragmentBannerAdapter) adapter).realCount();
        }
        return realPosition;
    }


    //获取适配器
    protected abstract AD getAdapterForViewPager();

    public abstract void addResource(ArrayList<T> arrayList);

    public void setProgramInfo(int program_list_id, int program_id, long uuid) {
        this.program_list_id = program_list_id;
        this.program_id = program_id;
        this.uuid = (int) uuid;
        String tag = uuid + "" + program_list_id + "" + program_id;
        Log.e("注册 轮播","  当前="+tag +"  program_id="+program_id);
        register(tag);
    }

    protected abstract void register(String tag);


    public void startPlayNow() {
        isTaskPostDelayed = true;
        if (viewPager2 != null && adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            int currentItem = viewPager2.getCurrentItem();
            int realPosition = toRealPosition(currentItem);
            sendPlayState(realPosition, PlayerState.State.Start);
        }
    }


    public void pausePlayNow() {
        isTaskPostDelayed = false;
        if (viewPager2 != null && adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            int currentItem = viewPager2.getCurrentItem();
            int realPosition = toRealPosition(currentItem);
            sendPlayState(realPosition, PlayerState.State.Pause);
        }
    }

    public void stopPlayNow() {
        isTaskPostDelayed = false;
        if (viewPager2 != null && adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            int currentItem = viewPager2.getCurrentItem();
            int realPosition = toRealPosition(currentItem);
            sendPlayState(realPosition, PlayerState.State.Rest);
            setCurrentItem(0, false);
        }
    }



    public void releasePlayNow() {
        if (viewPager2 != null && adapter != null && adapter instanceof BasicFragmentBannerAdapter) {
            int currentItem = viewPager2.getCurrentItem();
            int realPosition = toRealPosition(currentItem);
            sendPlayState(realPosition, PlayerState.State.Release);
        }
        String tag = uuid + "" + program_list_id + "" + program_id;
        unRegister(tag);
        Rxbus.getInStance().unRegisterRxBus(Field_Banner_Player.Fragment_Banner_Player, tag);
    }

    protected abstract void unRegister(String tag);

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            startX = lastX = ev.getRawX();
            startY = lastY = ev.getRawY();
        } else if (action == MotionEvent.ACTION_MOVE) {
            lastX = ev.getRawX();
            lastY = ev.getRawY();
            if (viewPager2.isUserInputEnabled()) {
                float distanceX = Math.abs(lastX - startX);
                float distanceY = Math.abs(lastY - startY);
                boolean disallowIntercept;
                if (viewPager2.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {
                    disallowIntercept = distanceX > scaledTouchSlop && distanceX > distanceY;
                } else {
                    disallowIntercept = distanceY > scaledTouchSlop && distanceY > distanceX;
                }
                getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
            }
        } else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            return Math.abs(lastX - startX) > scaledTouchSlop || Math.abs(lastY - startY) > scaledTouchSlop;
        }
        return super.onInterceptTouchEvent(ev);
    }

    /**
     * 预加载 不推荐使用
     *
     * @param limit
     * @return
     */
    public NewViewPagerBanner<T, AD, HV> setOffscreenPageLimit(int limit) {
        if (limit >= 1)
            viewPager2.setOffscreenPageLimit(limit);
        return this;
    }

    /**
     * 设置翻页滚动时间，时间太短看不出翻页效果
     *
     * @param time
     * @return
     */
    public NewViewPagerBanner<T, AD, HV> setNeedAnimationTime(int time) {
        if (time > 0) {
            isNeedAnimation = true;
            initLayoutManager(time);
        } else {
            isNeedAnimation = false;
            RecyclerView recyclerView = (RecyclerView) viewPager2.getChildAt(0);
            recyclerView.setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
            LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
            recyclerView.setLayoutManager(layoutManager);
            proxyLayoutManger = null;
        }
        return this;
    }

    /**
     * 添加翻页动画效果
     *
     * @param trans
     * @return
     */
    public NewViewPagerBanner<T, AD, HV> addPageTransOption
    (@IntRange(from = 0, to = 17) int trans) {
        ViewPager2.PageTransformer pageTransformer = AnimationTools.getInStance().takeAnimationTransformer(trans);
        if (pageTransformer != null) {
            isNeedAnimation = true;
            compositePageTransformer.addTransformer(pageTransformer);
        }
        return this;
    }

    public NewViewPagerBanner<T, AD, HV> addPageTransformer(ViewPager2.PageTransformer transformer) {
        compositePageTransformer.addTransformer(transformer);
        isNeedAnimation = true;
        return this;
    }

    public NewViewPagerBanner<T, AD, HV> setIndicator(Indicator indicator) {
        return setIndicator(indicator, true);
    }

    /**
     * 翻页
     *
     * @return
     */
    public boolean playNext() {
        tempPosition++;
        Log.e("翻页", isTaskPostDelayed + "=============" + tempPosition
                + "  ===" + getRealCount() + "  sidePage=" + sidePage);
        if (!isTaskPostDelayed) {
            return false;
        }
        if (getRealCount() == 0) {
            return false;
        }
        if (getRealCount() == 1) {
            sendPlayState(0, PlayerState.State.Start);
            return false;
        }
        isBeginPagerChange = true;

        if (tempPosition >= getRealCount() + sidePage) {
            isBeginPagerChange = false;
            viewPager2.setCurrentItem(sidePage, false);
//            playNext();
        } else {
            isBeginPagerChange = true;
            viewPager2.setCurrentItem(tempPosition,
                    isNeedAnimation);
        }
        return true;

    }


    /**
     * 设置indicator，支持在xml中创建
     *
     * @param attachToRoot true 添加到banner布局中
     */
    public NewViewPagerBanner<T, AD, HV> setIndicator(Indicator indicator, boolean attachToRoot) {
        if (this.indicator != null) {
            removeView(this.indicator.getView());
        }
        if (indicator != null) {
            this.indicator = indicator;
            if (attachToRoot) {
                addView(this.indicator.getView(), this.indicator.getParams());
            }
        }
        return this;
    }

    /**
     * 设置一屏多页
     *
     * @param multiWidth 左右页面露出来的宽度一致
     * @param pageMargin item与item之间的宽度
     */
    public NewViewPagerBanner<T, AD, HV> setPageMargin(int multiWidth, int pageMargin) {
        return setPageMargin(multiWidth, multiWidth, pageMargin);
    }

    /**
     * 设置一屏多页
     *
     * @param tlWidth    左边页面显露出来的宽度
     * @param brWidth    右边页面露出来的宽度
     * @param pageMargin item与item之间的宽度
     */
    public NewViewPagerBanner<T, AD, HV> setPageMargin(int tlWidth, int brWidth, int pageMargin) {
        if (pageMargin < 0) pageMargin = 0;
        addPageTransformer(new MarginPageTransformer(pageMargin));
        RecyclerView recyclerView = (RecyclerView) viewPager2.getChildAt(0);
        if (viewPager2.getOrientation() == ViewPager2.ORIENTATION_VERTICAL) {
            recyclerView.setPadding(viewPager2.getPaddingLeft(), tlWidth + Math.abs(pageMargin), viewPager2.getPaddingRight(), brWidth + Math.abs(pageMargin));
        } else {
            recyclerView.setPadding(tlWidth + Math.abs(pageMargin), viewPager2.getPaddingTop(), brWidth + Math.abs(pageMargin), viewPager2.getPaddingBottom());
        }
        recyclerView.setClipToPadding(false);
        needPage = Field_Banner.NORMAL_COUNT + Field_Banner.NORMAL_COUNT;
        sidePage = Field_Banner.NORMAL_COUNT;
        if (adapter != null) {
            if (adapter instanceof BasicFragmentBannerAdapter) {
                ((BasicFragmentBannerAdapter) adapter).setNeedPage(needPage)
                        .setSidePage(sidePage);
            }
        }
        return this;
    }


    public void setCurrentItem(int position, boolean smoothScroll) {
        tempPosition = position + sidePage;
        viewPager2.setCurrentItem(tempPosition, smoothScroll);
    }

    public void release() {
        releasePlayNow();
        if (viewPager2 != null) {
            this.removeView(viewPager2);
            viewPager2.unregisterOnPageChangeCallback(changeCallback);
            viewPager2.removeAllViewsInLayout();
            viewPager2 = null;
        }
    }


    public void accept(PlayerState playerState) throws Exception {
        if (playerState == null) {
            return;
        }
        int program_list_id = playerState.getProgram_list_id();
        int program_id = playerState.getProgram_id();
        if (this.program_list_id != program_list_id) {
            return;
        }
        if (this.program_id != program_id) {
            return;
        }
        Log.e("接受指令 轮播主键","接受节目="+program_id+"  当前节目="+this.program_id);
        switch (playerState.getState()) {
            case PlayerState.State.Start:
                startPlayNow();
                break;
            case PlayerState.State.Pause:
                pausePlayNow();
                break;
            case PlayerState.State.Stop:
            case PlayerState.State.Rest:
                stopPlayNow();
                break;
            case PlayerState.State.Release:
                releasePlayNow();
                break;
        }

    }

    /**
     * 发送信息播放
     *
     * @param position
     * @param state
     */
    public void sendPlayState(int position, int state) {
        if (viewPager2 == null) {
            return;
        }
        PlayerState playerState = new PlayerState();
        playerState.setProgram_list_id(program_list_id);
        playerState.setProgram_id(program_id);
        playerState.setPosition(position);
        playerState.setState(state);
        Log.e("发送指令  轮播","节目单："+program_id +"  item="+position+"  播放="+state);
        Rxbus.getInStance().post(Field_Banner_Player.Fragment_Player, playerState);
    }


}
